using System;
using UnityEngine;

[Serializable]
public class TTCameraBehaviourRacketPlayer : TTCameraBehaviour
{
	public Vector3 cameraDisplace = new Vector3(0f, 2f, 3.75f);

	public float camLookAtYDisplace;

	public float camPosZFactor = 0.75f;

	public float viewDirectionFactor = 1f;

	public float camPosXFactor = 1.5f;

	public FloatRange zRange = new FloatRange
	{
		min = -1f,
		max = 10f
	};

	public float racketx;

	public float racketxReturn;

	public float returnMoveSpeed = 2f;

	public float returnMoveRot = 2f;

	public bool usePlayerStear = true;

	public float durationTillPlayerStearFullyActive = 0.25f;

	public float xtoz;

	public float serveViewDirectionFactor;

	public bool recalculateFocusPoint;

	public float focusPointTime;

	private TableTennisHumanPlayerRacket humanPlayer_;

	public TableTennisHumanPlayerRacket humanPlayer
	{
		get
		{
			return humanPlayer_;
		}
		set
		{
			humanPlayer_ = value;
		}
	}

	private PhysicsBall ball
	{
		get
		{
			return humanPlayer.match.ball;
		}
	}

	protected int tableSide
	{
		get
		{
			return humanPlayer.tableSide;
		}
	}

	protected override Quaternion DesiredRotation()
	{
		Vector3 vector = DesiredPosition();
		Vector3 vector2 = new Vector3(0f, Table.tabletopy + camLookAtYDisplace, 0f);
		PhysicsBall physicsBall = humanPlayer.match.ball;
		FlightSequence.FlightPlanStage stageThatStartsFromTableSide = ball.flightSequence.GetStageThatStartsFromTableSide(tableSide);
		if (ball != null && stageThatStartsFromTableSide != null && !humanPlayer.IsInServe())
		{
			if (ball.playerThatHitBall == humanPlayer)
			{
				return camera.transform.rotation;
			}
			Vector3 vector3 = humanPlayer.highestPositionAfterRebound;
			if (recalculateFocusPoint)
			{
				vector3 = stageThatStartsFromTableSide.flight.PositionAt(stageThatStartsFromTableSide.duration * focusPointTime);
			}
			float num = ((float)tableSide * Table.halfLength - vector3.z) * camPosZFactor;
			vector2.z -= Mathf.Clamp(num / Table.halfLength, zRange.min, zRange.max) * Table.halfLength;
			vector2.x = vector.x * viewDirectionFactor;
			vector2.z += (float)humanPlayer.tableSide * Mathf.Abs(vector.x) * xtoz;
		}
		else if (ball != null && humanPlayer.IsInServe())
		{
			vector2.x += physicsBall.position.x * racketx * serveViewDirectionFactor;
		}
		else if (humanPlayer.match.Other(humanPlayer).IsInServe())
		{
			vector2.x += humanPlayer.racket.position.x * racketx * serveViewDirectionFactor;
		}
		else if (physicsBall.isBallInGame && ball == null)
		{
			vector2.x += humanPlayer.racket.position.x * racketx * racketxReturn;
		}
		return Quaternion.LookRotation(vector2 - vector);
	}

	protected override Vector3 DesiredPosition()
	{
		Vector3 result = new Vector3(0f, cameraDisplace.y, 0f);
		FlightSequence.FlightPlanStage stageThatStartsFromTableSide = ball.flightSequence.GetStageThatStartsFromTableSide(tableSide);
		if (ball != null && stageThatStartsFromTableSide != null && !humanPlayer.IsInServe())
		{
			if (ball.playerThatHitBall == humanPlayer)
			{
				return camera.transform.position;
			}
			Vector3 vector = humanPlayer.highestPositionAfterRebound;
			if (recalculateFocusPoint)
			{
				vector = stageThatStartsFromTableSide.flight.PositionAt(stageThatStartsFromTableSide.duration * focusPointTime);
			}
			result = vector;
			result.y = cameraDisplace.y;
			result.z = (Table.halfLength + cameraDisplace.z) * (float)tableSide;
			float num = ((float)tableSide * Table.halfLength - vector.z) * camPosZFactor;
			result.z -= Mathf.Clamp(num / Table.halfLength, zRange.min, zRange.max) * Table.halfLength;
			result.x *= camPosXFactor;
		}
		else
		{
			PhysicsBall physicsBall = humanPlayer.match.ball;
			if (ball != null && humanPlayer.IsInServe())
			{
				result.x += physicsBall.position.x * racketx;
			}
			else if (humanPlayer.match.Other(humanPlayer).IsInServe())
			{
				result.x += humanPlayer.racket.position.x * racketx;
			}
			else if (physicsBall.isBallInGame && ball == null)
			{
				result.x += humanPlayer.racket.position.x * racketx * racketxReturn;
			}
			result.z = (Table.halfLength + cameraDisplace.z) * (float)tableSide;
		}
		result.x += cameraDisplace.x;
		result.z += (float)humanPlayer.tableSide * Mathf.Abs(result.x) * xtoz;
		return result;
	}

	public override void Start(Camera cam, TTCameraController camController, TTCameraOptions cameraOptions)
	{
		base.Start(cam, camController, cameraOptions);
		humanPlayer = cameraOptions.player as TableTennisHumanPlayerRacket;
	}

	public override void Update()
	{
		PhysicsBall physicsBall = humanPlayer.match.ball;
		float num = ((!(ball != null) && physicsBall.isBallInGame) ? returnMoveSpeed : moveSpeed);
		float num2 = num;
		Transform transform = camera.transform;
		float deltaTime = RealTime.deltaTime;
		transform.position = Vector3.Lerp(transform.position, DesiredPosition(), deltaTime * num);
		transform.rotation = Quaternion.Lerp(transform.rotation, DesiredRotation(), deltaTime * num2);
		camera.fieldOfView = Mathf.Lerp(camera.fieldOfView, fov, deltaTime * num);
	}
}
